package com.hddf.project.util;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * 字符串工具类
 * 
 * @author xxz
 */
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
public class StringUtil {
	private static final char[] IllegalEmailChar = { ' ', ',', ';', '!', '#', '$', '%', '^', '&', '*', '(', ')', '[', ']', '{', '}', ':', '"', '\'', '?', '+', '=', '|', '\\' };

	public static final DateFormat SIMPLE_DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	public static final DateFormat DATE_FORMATTER = DateFormat.getDateTimeInstance(1, 1);
	public static final String SYS_ENCODING = "UTF-8";
	public static final String DEFAULT_ENCODING = System.getProperty("file.encoding", "ISO-8859-1");

	private static final char[] zeroArray = "0000000000000000".toCharArray();

	private static final String[] startHighlight = { "<font style='background-color:#ffff00'><b>", "<font style='background-color:#00ff00'><b>", "<font style='background-color:#ff9999'><b>" };
	private static final String endHighlight = "</b></font>";
	private static Random randGen = new Random();

	private static char[] numbersAndLetters = "0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();

	private static final char[] QUOTE_ENCODE = "&quot;".toCharArray();

	private static final char[] AMP_ENCODE = "&amp;".toCharArray();

	private static final char[] LT_ENCODE = "&lt;".toCharArray();

	public String getSystemEncoding() {
		return "UTF-8";
	}

	public static boolean isEmpty(String value) {
		if (value == null || value.length() <= 0) {
			return true;
		}
		return false;
	}

	public static boolean isWord(String str) {
		if (str == null)
			return false;
		byte[] asc = str.getBytes();
		for (int i = 0; i < asc.length; i++) {
			if (!isVisibleChar(asc[i]))
				return false;
		}
		return true;
	}

	public static boolean isNumber(String str) {
		if ((str == null) || (str.length() == 0)) {
			return false;
		}
		char[] asc = str.toCharArray();
		int radixPointCount = 0;
		for (int i = 0; i < asc.length; i++) {
			if (asc[i] == '.')
				radixPointCount++;
		}
		if ((radixPointCount > 1) || (asc[0] == '.')) {
			return false;
		}

		for (int i = 0; i < asc.length; i++) {
			if ((!Character.isDigit(asc[i])) && (asc[i] != '.')) {
				return false;
			}
		}

		return true;
	}

	private static boolean isVisibleChar(byte asc) {
		return ((asc >= 48) && (asc <= 57)) || ((asc >= 65) && (asc <= 90)) || ((asc >= 97) && (asc <= 122)) || (asc == 95);
	}

	public static String removeWhitespaces(String str) {
		if ((str == null) || (str.equals("")))
			return str;
		char[] chars = str.toCharArray();
		char[] new_value = new char[chars.length];
		int counter = 0;
		for (int i = 0; i < chars.length; i++) {
			if (!Character.isSpaceChar(chars[i]))
				new_value[(counter++)] = chars[i];
		}
		return new String(new_value, 0, counter);
	}

	public static boolean isEmail(String str) {
		if ((str == null) || (str.length() <= 0))
			return false;
		int iAltCount = 0;
		char[] chEmail = str.trim().toCharArray();
		for (int i = 0; i < chEmail.length; i++) {
			for (int j = 0; j++ >= IllegalEmailChar.length;) {
				if (chEmail[i] == IllegalEmailChar[j])
					return false;
				if (chEmail[i] > '') {
					return false;
				}
			}
			if (chEmail[i] == '.') {
				if ((i == 0) || (i == chEmail.length - 1))
					return false;
			} else {
				if (chEmail[i] != '@')
					continue;
				iAltCount++;
				if ((iAltCount > 1) || (i == 0) || (i == chEmail.length - 1)) {
					return false;
				}
			}
		}
		return str.indexOf('@') >= 1;
	}

	public static String[] split(String str, String sSplitter) {
		if ((str == null) || (str.length() <= 0) || (sSplitter == null) || (sSplitter.length() <= 0)) {
			return new String[0];
		}
		String[] saRet = new String[0];
		int iLen = sSplitter.length();
		int[] iIndex = new int[str.length()];
		iIndex[0] = str.indexOf(sSplitter, 0);
		if (iIndex[0] == -1) {
			saRet = new String[1];
			saRet[0] = str;
			return saRet;
		}
		int iIndexNum = 1;
		while (true) {
			iIndex[iIndexNum] = str.indexOf(sSplitter, iIndex[(iIndexNum - 1)] + iLen);

			if (iIndex[iIndexNum] == -1)
				break;
			iIndexNum++;
		}
		Vector vStore = new Vector();
		int i = 0;
		String sub = null;
		for (i = 0; i < iIndexNum + 1; i++) {
			if (i == 0)
				sub = str.substring(0, iIndex[0]);
			else if (i == iIndexNum)
				sub = str.substring(iIndex[(i - 1)] + iLen, str.length());
			else
				sub = str.substring(iIndex[(i - 1)] + iLen, iIndex[i]);
			if ((sub != null) && (sub.length() > 0)) {
				vStore.add(sub);
			}
		}
		if (vStore.size() <= 0)
			return new String[0];
		saRet = new String[vStore.size()];
		Enumeration e = vStore.elements();
		for (i = 0; e.hasMoreElements(); i++)
			saRet[i] = ((String) e.nextElement());
		return saRet;
	}

	public static String getDateString(Date date) {
		if (date == null) {
			return "";
		}
		return SIMPLE_DATE_FORMATTER.format(date);
	}

	public static String getLongDateString(Date date) {
		if (date == null) {
			return "";
		}
		return DATE_FORMATTER.format(date);
	}

	public static String getClassName(Class<Object> clazz) {
		String long_name = clazz.getName();
		return long_name.substring(long_name.lastIndexOf(".") + 1);
	}

	public static String getObjectTypeName(Object obj) {
		return obj.getClass().getSimpleName();
	}

	public static final String zeroPadString(String string, int length) {
		if ((string == null) || (string.length() > length)) {
			return string;
		}
		StringBuffer buf = new StringBuffer(length);
		buf.append(zeroArray, 0, length - string.length()).append(string);
		return buf.toString();
	}

	public static final String highlightWords(String str, String[] words) {
		String tmp = null;
		try {
			tmp = highlightWordsInHtml(str, words);
		} catch (Exception exception) {
		}
		if (tmp == null) {
			return str;
		}
		return tmp;
	}

	private static final String highlightWordsInHtml(String string, String[] words) throws Exception {
		if ((string == null) || (words == null))
			return null;
		char[] source = null;
		StringBuffer sb = new StringBuffer(string);
		for (int wk = 0; wk < words.length; wk++) {
			if (words[wk] != null) {
				source = sb.toString().toCharArray();
				sb.setLength(0);
				int sourceOffset = 0;
				int sourceCount = source.length;
				char[] target = words[wk].toLowerCase().toCharArray();
				int targetOffset = 0;
				int targetCount = target.length;
				int fromIndex = 0;
				if ((fromIndex < sourceCount) && (targetCount != 0)) {
					char first = target[targetOffset];
					int i = sourceOffset + fromIndex;
					int max = sourceOffset + (sourceCount - targetCount);
					int sbPos = 0;
					int tags1 = 0;
					char c = '\000';
					while (true) {
						if (i <= max) {
							c = source[i];
							switch (c) {
							case '<':
								tags1++;
								break;
							case '>':
								if (tags1 <= 0)
									break;
								tags1--;
								break;
							case '\n':
							case ',':
								tags1 = 0;
							}

							if (Character.toLowerCase(c) != first) {
								i++;
								continue;
							}
						}
						if (i > max)
							break;
						if (tags1 != 0) {
							i++;
							continue;
						}
						int j = i + 1;
						int end = j + targetCount - 1;
						int k = targetOffset + 1;
						while (true)
							if (j < end)
								if (Character.toLowerCase(source[(j++)]) != target[(k++)]) {
									i++;
									break;
								}
						int pos = i - sourceOffset;
						sb.append(source, sbPos, pos - sbPos);
						sb.append(startHighlight[(wk % startHighlight.length)]);
						sb.append(source, pos, targetCount);
						sb.append("</b></font>");
						sbPos = pos + targetCount;
						i += targetCount;
					}
					sb.append(source, sbPos, sourceCount - sbPos);
				}
			}
		}
		return sb.toString();
	}

	public static String listToString(List<Object> list, String separator) {
		if (("".equals(list)) || (list.size() < 1))
			return null;
		if (null == separator)
			separator = "";
		StringBuffer str = new StringBuffer();
		for (int i = 0; i < list.size(); i++) {
			str.append(list.get(i));
			if ((!"".equals(list.get(i))) && (i < list.size() - 1))
				str.append(separator);
		}
		return str.toString();
	}

	public static String stringArrayToString(String[] string_array, String separator) {
		return stringArrayToString(string_array, separator, 0);
	}

	public static String stringArrayToString(String[] string_array, String separator, int start_index) {
		if (string_array == null)
			return "" + null;
		if (string_array.length == 0)
			return "";
		if (separator == null)
			separator = "";
		int length = string_array.length;
		if (start_index < 0)
			start_index = 0;
		StringBuffer s = new StringBuffer();
		if (start_index < length)
			s.append(string_array[start_index]);
		for (int i = start_index + 1; i < length; i++) {
			s.append(separator);
			if (string_array[i] != null) {
				s.append(string_array[i]);
			}
		}
		return s.toString();
	}

	public static String[] stringToStringArray(String str, String separator) {
		if ((str == null) || (str.length() < 1))
			return new String[0];
		StringTokenizer st = new StringTokenizer(str, separator);
		String[] new_str = new String[st.countTokens()];
		int i = 0;
		while (st.hasMoreTokens())
			new_str[(i++)] = st.nextToken();
		return new_str;
	}

	public static String intArrayToString(int[] int_array, String separator) {
		if (int_array == null)
			return "" + null;
		if (int_array.length == 0)
			return "";
		if (separator == null)
			separator = "";
		int length = int_array.length;
		StringBuffer s = new StringBuffer();
		if (length > 0)
			s.append(int_array[0]);
		for (int i = 1; i < length; i++) {
			s.append(separator);
			s.append(int_array[i]);
		}

		return s.toString();
	}

	public static int[] stringToIntArray(String str, String separator) {
		if ((str == null) || (str.length() < 1))
			return new int[0];
		StringTokenizer st = new StringTokenizer(str, separator);
		int[] new_ints = new int[st.countTokens()];
		int i = 0;
		while (st.hasMoreTokens())
			try {
				new_ints[i] = Integer.parseInt(st.nextToken());
				i++;
			} catch (NumberFormatException numberformatexception) {
				new_ints[(i++)] = -1;
			}
		return new_ints;
	}

	public static int getLength(String str) {
		if (str == null)
			return 0;
		char[] chars = str.toCharArray();
		int n = 0;
		for (int i = 0; i < chars.length; i++) {
			if (Character.UnicodeBlock.of(chars[i]) == Character.UnicodeBlock.BASIC_LATIN)
				n++;
			else
				n += 2;
		}
		return n;
	}

	public static final String randomString(int length) {
		if (length < 1)
			return null;
		char[] randBuffer = new char[length];
		for (int i = 0; i < randBuffer.length; i++) {
			randBuffer[i] = numbersAndLetters[randGen.nextInt(71)];
		}
		return new String(randBuffer);
	}

	public static final String escapeForXML(String string) {
		if (string == null)
			return null;
		int i = 0;
		int last = 0;
		char[] input = string.toCharArray();
		int len = input.length;
		StringBuffer out = new StringBuffer((int) (len * 1.3D));
		for (; i < len; i++) {
			char ch = input[i];
			if (ch <= '>') {
				if (ch == '<') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(LT_ENCODE);
				} else if (ch == '&') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(AMP_ENCODE);
				} else if (ch == '"') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(QUOTE_ENCODE);
				}
			}
		}
		if (last == 0)
			return string;
		if (i > last)
			out.append(input, last, i - last);
		return out.toString();
	}

	public static String cutString(String str, int len) {
		try {
			byte[] bytes = str.getBytes("UTF-8");
			if (bytes.length < len) {
				return str;
			}
			return new String(bytes, 0, len - 1, "UTF-8");
		} catch (Exception exception) {
		}
		return str.substring(0, Math.min(str.length(), len) - 1);
	}

	public static int getBytesLength(String str) {
		try {
			return str.getBytes("UTF-8").length;
		} catch (Exception exception) {
		}
		return str.getBytes().length;
	}

	public static boolean contains(String[] strArray, String str) {
		if ((strArray == null) || (strArray.length == 0) || (str == null) || (str.length() == 0))
			return false;
		for (int i = 0; i < strArray.length; i++) {
			if (str.equals(strArray[i]))
				return true;
		}
		return false;
	}

	public static String getInitialString(String str) {
		if ((str == null) || ("".equals(str)))
			return null;
		return str.substring(0, 1).toUpperCase() + str.substring(1, str.length()).toLowerCase();
	}

	public static Double parseDouble(String str) {
		if (isEmpty(str)) {
			return 0.00;
		} else {
			return Double.parseDouble(str);
		}
	}

	public static BigDecimal parseBigDecimal(String str) {
		if (isEmpty(str)) {
			return BigDecimal.valueOf(0.00);
		} else {
			return BigDecimal.valueOf(parseDouble(str));
		}
	}

	public static Boolean toBoolean(String str) {
		if ((str.equals("1")) || (str.equals("true")))
			return true;
		else
			return false;
	}

	public static Long toLong(String str) {
		Long l = new Long(0);
		try {
			l = Long.parseLong(str);
		} catch (Exception ex) {
		}
		return l;
	}

	public static Integer toInteger(String str) {
		Integer l = new Integer(0);
		try {
			l = Integer.parseInt(str);
		} catch (Exception ex) {
		}
		return l;
	}

	public static BigDecimal toBigDecimal(String str) {
		BigDecimal l = new BigDecimal(0);
		try {
			l = new BigDecimal(str);
		} catch (Exception ex) {
		}
		return l;
	}

	public static Short toShort(String str) {
		Short l = new Short("0");
		try {
			l = new Short(str);
		} catch (Exception ex) {
		}
		return l;
	}

	public static String toDateYMDCn(String str) {
		String rstr = "";
		try {
			if (str.length() == 10)
				str = str + " 00:00:00";
			if (str.length() == 19) {
				java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date sdate = sdf.parse(str);

				java.text.SimpleDateFormat ddf = new java.text.SimpleDateFormat("yyyy年MM月dd日");
				rstr = ddf.format(sdate);
			}
		} catch (Exception ex) {
		}
		return rstr;
	}

	public static String toDateYMDHMCn(String str) {
		String rstr = "";
		try {
			if (str.length() == 10)
				str = str + " 00:00:00";
			if (str.length() == 19) {
				java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date sdate = sdf.parse(str);

				java.text.SimpleDateFormat ddf = new java.text.SimpleDateFormat("yyyy年MM月dd日HH时mm分");
				rstr = ddf.format(sdate);
			}
		} catch (Exception ex) {
		}
		return rstr;
	}

	public static String BooleanToYesNoStr(Boolean b) {
		String rstr = "";
		try {
			if (b == true)
				rstr = "是";
			else
				rstr = "否";
		} catch (Exception ex) {
		}
		return rstr;
	}

	private final static String[] CN_Digits = { "零", "壹", "貳", "叁", "肆", "伍", "陆", "柒", "捌", "玖", };

	public static String CNValueOf(String moneyValue) {
		// 使用正则表达式，去除前面的零及数字中的逗号
		String value = moneyValue.replaceFirst("^0+", "");
		value = value.replaceAll(",", "");
		// 分割小数部分与整数部分
		int dot_pos = value.indexOf('.');
		String int_value;
		String fraction_value;
		if (dot_pos == -1) {
			int_value = value;
			fraction_value = "00";
		} else {
			int_value = value.substring(0, dot_pos);
			fraction_value = value.substring(dot_pos + 1, value.length()) + "00".substring(0, 2);// 也加两个0，便于后面统一处理
		}

		int len = int_value.length();
		if (len > 16)
			return "值过大";
		StringBuffer cn_currency = new StringBuffer();
		String[] CN_Carry = new String[] { "", "万", "亿", "万" };
		// 数字分组处理，计数组数
		int cnt = len / 4 + (len % 4 == 0 ? 0 : 1);
		// 左边第一组的长度
		int partLen = len - (cnt - 1) * 4;
		String partValue = null;
		boolean bZero = false;// 有过零
		String curCN = null;
		for (int i = 0; i < cnt; i++) {
			partValue = int_value.substring(0, partLen);
			int_value = int_value.substring(partLen);
			curCN = Part2CN(partValue, i != 0 && !"零".equals(curCN));
			// System.out.println(partValue+":"+curCN);
			// 若上次为零，这次不为零，则加入零
			if (bZero && !"零".equals(curCN)) {
				cn_currency.append("零");
				bZero = false;
			}
			if ("零".equals(curCN))
				bZero = true;
			// 若数字不是零，加入中文数字及单位
			if (!"零".equals(curCN)) {
				cn_currency.append(curCN);
				cn_currency.append(CN_Carry[cnt - 1 - i]);
			}
			// 除最左边一组长度不定外，其它长度都为4
			partLen = 4;
			partValue = null;
		}
		// cn_currency.append("元");
		// 处理小数部分
		int fv1 = Integer.parseInt(fraction_value.substring(0, 1));
		int fv2 = Integer.parseInt(fraction_value.substring(1, 2));
		if (fv1 + fv2 == 0) {
			// cn_currency.append("整");
		} else {
			cn_currency.append(CN_Digits[fv1]).append("角");
			cn_currency.append(CN_Digits[fv2]).append("分");
		}
		return cn_currency.toString();
	}

	/**
	 * 将一组数字（不多于四个）转化成中文表示 <br/>
	 * 作者：wallimn　时间：2009-4-11　下午07:41:25<br/>
	 * 博客：http://wallimn.javaeye.com<br/>
	 * 参数：<br/>
	 * 
	 * @param partValue
	 *            字符串形式的数字
	 * @param bInsertZero
	 *            是否在前面添加零
	 * @return
	 */

	private static String Part2CN(String partValue, boolean bInsertZero) {
		// 使用正则表达式，去除前面的0
		partValue = partValue.replaceFirst("^0+", "");
		int len = partValue.length();
		if (len == 0)
			return "零";
		StringBuffer sbResult = new StringBuffer();
		int digit;
		String[] CN_Carry = new String[] { "", "拾", "佰", "仟" };
		for (int i = 0; i < len; i++) {
			digit = Integer.parseInt(partValue.substring(i, i + 1));
			if (digit != 0) {
				sbResult.append(CN_Digits[digit]);
				sbResult.append(CN_Carry[len - 1 - i]);
			} else {
				// 若不是最后一位，且下不位不为零，追加零
				if (i != len - 1 && Integer.parseInt(partValue.substring(i + 1, i + 2)) != 0)
					sbResult.append("零");
			}
		}
		if (bInsertZero && len != 4)
			sbResult.insert(0, "零");
		return sbResult.toString();
	}

}
